﻿#pragma once

#include <cpptools/db/mysqlpp_pool.h>
#include <cpptools/mt/tpool.hpp>

#include "PubMoveFunction.h"
#include "PubMysqlppPool.h"
#include "PubTpool.h"

namespace google::protobuf { class Message; }

struct Main {
    using dbpool_t = pub::MysqlppPoolWait; // 数据库连接池类型
    using tpool_t = pub::Tpool; // 线程池类型
    using func_t = std::move_only_function<void(void)>; //pub::MoveFunc; //pub::MoveArgsFunc<void(void)>;

    static dbpool_t*                    dbpool; // 数据库连接池
    static tpool_t*                     tpool; // 线程池管理对象
    static std::string                  secret; // 加密密钥
    static uint32_t                     timeout; // 默认超时时间(秒）
    static int                          epollFd; // 主线程epoll句柄
    static int                          eventFd; // 主线程eventfd句柄，用于任务线程通知主线程处理任务
    static uint32_t                     beginTimesec; // 程序启动时间

    // 发送日志
    static void sendLog(const google::protobuf::Message& msg, uint8_t logType);
    
    // 推送任务到主线程
    static std::deque<func_t> tasks; // 推送任务队列
    static std::mutex mtx; // 推送任务回主线程锁
    template<typename F> static void post(F&& __f) {
        mtx.lock();
        tasks.emplace_back(std::forward<F>(__f));
        mtx.unlock();
        uint64_t val = 1;
        std::ignore = write(eventFd, &val, sizeof(val)); // 使用event通知主线程
    }

    constexpr static const char* kSystemName = "system"; // 系统帐号

    constexpr static const char* kDbName = "dcp5"; // 数据库表名称
    constexpr static const char* kTableNamePms = "pms";
    constexpr static const char* kTableNameRole = "role";
    constexpr static const char* kTableNameAccount = "acc";
    constexpr static const char* kTableNameTeam = "team";

    constexpr static const char* kPmsNamePmsRead = "acct.pms.read"; // 权限名称
    constexpr static const char* kPmsNamePmsWrite = "acct.pms.write";
    constexpr static const char* kPmsNameRoleRead = "acct.role.read";
    constexpr static const char* kPmsNameRoleWrite = "acct.role.write";
    constexpr static const char* kPmsNameAccRead = "acct.acc.read";
    constexpr static const char* kPmsNameAccWrite = "acct.acc.write";
    constexpr static const char* kPmsNameAccDelete = "acct.acc.del";
};


enum class out : uint64_t {
    kBaseInfo,
    kBaseErr,
    kConnInfo,
    kConnErr,
    kConnSend,
    kConnRecv,
    kLogInfo,
    kLogErr,
    kLogSend,
    kLogRecv,
    kApiPmsInfo,
    kApiPmsErr,
    kApiRoleInfo,
    kApiRoleErr,
    kApiAccInfo,
    kApiAccErr,
    kQueryInfo,
    kQueryErr,
    kQuerySend,
    kQueryRecv,
};